package org.abc.fund.entity.factorEntity;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import java.time.LocalDateTime;
import java.util.Map;

/**
 * 数据源配置实体类
 */
@Entity
@Table(name = "data_source_configs")
@Data
@EqualsAndHashCode(callSuper = false)
public class DataSourceConfig {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    /**
     * 数据源名称
     */
    @Column(nullable = false, length = 200)
    private String dataSourceName;

    /**
     * 数据源类型：WIND
     */
    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private DataSourceType dataSourceType;

    /**
     * 连接配置（JSON格式）
     */
    @Column(columnDefinition = "TEXT", nullable = false)
    private String connectionConfig;

    /**
     * 认证信息（JSON格式，加密存储）
     */
    @Column(columnDefinition = "TEXT")
    private String authConfig;

    /**
     * 数据表配置（JSON格式）
     */
    @Column(columnDefinition = "TEXT")
    private String tableConfig;

    /**
     * Python脚本（用于数据清洗）
     */
    @Column(columnDefinition = "TEXT")
    private String pythonScript;

    /**
     * 调度配置（JSON格式）
     */
    @Column(columnDefinition = "TEXT")
    private String scheduleConfig;

    /**
     * 是否启用
     */
    @Column(nullable = false)
    private Boolean enabled = true;

    /**
     * 最后同步时间
     */
    @Column
    private LocalDateTime lastSyncTime;

    /**
     * 创建时间
     */
    @CreationTimestamp
    @Column(nullable = false, updatable = false)
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    @UpdateTimestamp
    @Column(nullable = false)
    private LocalDateTime updateTime;

    /**
     * 创建人
     */
    @Column(length = 100)
    private String createdBy;

    /**
     * 更新人
     */
    @Column(length = 100)
    private String updatedBy;

    // ========== 前端兼容字段 ==========

    /**
     * 前端字段：数据源名称
     */
    @Transient
    private String name;

    /**
     * 前端字段：数据源类型
     */
    @Transient
    private String type;

    /**
     * 前端字段：连接地址
     */
    @Transient
    private String url;

    /**
     * 前端字段：用户名
     */
    @Transient
    private String username;

    /**
     * 前端字段：密码
     */
    @Transient
    private String password;

    /**
     * 前端字段：描述
     */
    @Transient
    private String description;

    /**
     * 前端字段：最后更新时间
     */
    @Transient
    private String lastUpdateTime;

    // ========== 便捷方法，用于兼容前端 ==========

    /**
     * 获取数据源名称（兼容方法）
     */
    public String getName() {
        return this.dataSourceName != null ? this.dataSourceName : this.name;
    }

    /**
     * 设置数据源名称（兼容方法）
     */
    public void setName(String name) {
        this.dataSourceName = name;
        this.name = name;
    }

    /**
     * 获取数据源类型（兼容方法）
     */
    public String getType() {
        if (this.dataSourceType != null) {
            return this.dataSourceType.name();
        }
        return this.type != null ? this.type : "CUSTOM";
    }

    /**
     * 设置数据源类型（兼容方法）
     */
    public void setType(String type) {
        this.type = type;
        try {
            this.dataSourceType = DataSourceType.valueOf(type.toUpperCase());
        } catch (IllegalArgumentException e) {
            this.dataSourceType = DataSourceType.CUSTOM;
        }
    }

    /**
     * 获取连接URL（从connectionConfig中解析）
     */
    public String getUrl() {
        if (this.url != null) {
            return this.url;
        }
        // 尝试从connectionConfig JSON中解析出URL
        if (this.connectionConfig != null && !this.connectionConfig.isEmpty()) {
            try {
                ObjectMapper mapper = new ObjectMapper();
                Map<String, Object> config = mapper.readValue(this.connectionConfig, new TypeReference<Map<String, Object>>() {});
                return (String) config.get("url");
            } catch (Exception e) {
                // 如果解析失败，直接返回connectionConfig
                return this.connectionConfig;
            }
        }
        return null;
    }

    /**
     * 设置连接URL（兼容方法）
     */
    public void setUrl(String url) {
        this.url = url;
        // 将URL保存到connectionConfig JSON中
        try {
            ObjectMapper mapper = new ObjectMapper();
            Map<String, Object> config = mapper.readValue(this.connectionConfig != null ? this.connectionConfig : "{}", new TypeReference<Map<String, Object>>() {});
            config.put("url", url);
            this.connectionConfig = mapper.writeValueAsString(config);
        } catch (Exception e) {
            // 如果JSON操作失败，直接保存URL
            this.connectionConfig = url;
        }
    }

    /**
     * 获取用户名（从authConfig中解析）
     */
    public String getUsername() {
        if (this.username != null) {
            return this.username;
        }
        // 尝试从authConfig JSON中解析出用户名
        if (this.authConfig != null && !this.authConfig.isEmpty()) {
            try {
                ObjectMapper mapper = new ObjectMapper();
                Map<String, Object> config = mapper.readValue(this.authConfig, new TypeReference<Map<String, Object>>() {});
                return (String) config.get("username");
            } catch (Exception e) {
                return null;
            }
        }
        return null;
    }

    /**
     * 设置用户名（兼容方法）
     */
    public void setUsername(String username) {
        this.username = username;
        // 将用户名保存到authConfig JSON中
        try {
            ObjectMapper mapper = new ObjectMapper();
            Map<String, Object> config = mapper.readValue(this.authConfig != null ? this.authConfig : "{}", new TypeReference<Map<String, Object>>() {});
            config.put("username", username);
            this.authConfig = mapper.writeValueAsString(config);
        } catch (Exception e) {
            // 如果JSON操作失败，直接保存用户名
            this.authConfig = "{\"username\":\"" + username + "\"}";
        }
    }

    /**
     * 获取密码（从authConfig中解析）
     */
    public String getPassword() {
        if (this.password != null) {
            return this.password;
        }
        // 尝试从authConfig JSON中解析出密码
        if (this.authConfig != null && !this.authConfig.isEmpty()) {
            try {
                ObjectMapper mapper = new ObjectMapper();
                Map<String, Object> config = mapper.readValue(this.authConfig, new TypeReference<Map<String, Object>>() {});
                return (String) config.get("password");
            } catch (Exception e) {
                return null;
            }
        }
        return null;
    }

    /**
     * 设置密码（兼容方法）
     */
    public void setPassword(String password) {
        this.password = password;
        // 将密码保存到authConfig JSON中
        try {
            ObjectMapper mapper = new ObjectMapper();
            Map<String, Object> config = mapper.readValue(this.authConfig != null ? this.authConfig : "{}", new TypeReference<Map<String, Object>>() {});
            config.put("password", password);
            this.authConfig = mapper.writeValueAsString(config);
        } catch (Exception e) {
            // 如果JSON操作失败，直接保存密码
            this.authConfig = "{\"password\":\"" + password + "\"}";
        }
    }

    /**
     * 获取描述
     */
    public String getDescription() {
        return this.description;
    }

    /**
     * 设置描述
     */
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     * 获取最后更新时间
     */
    public String getLastUpdateTime() {
        if (this.lastSyncTime != null) {
            return this.lastSyncTime.toString();
        }
        if (this.updateTime != null) {
            return this.updateTime.toString();
        }
        return this.lastUpdateTime;
    }

    /**
     * 设置最后更新时间
     */
    public void setLastUpdateTime(String lastUpdateTime) {
        this.lastUpdateTime = lastUpdateTime;
    }

    /**
     * 获取查询SQL（从tableConfig中解析）
     */
    public String getQuerySql() {
        // 这里可以从tableConfig JSON中解析出查询SQL
        // 简化实现，实际应该解析JSON
        return this.tableConfig;
    }

    /**
     * 设置查询SQL（兼容方法）
     */
    public void setQuerySql(String querySql) {
        this.tableConfig = querySql;
    }

    // ========== 数据源类型枚举 ==========

    public enum DataSourceType {
        WIND("Wind数据库"),
        JUVUAN("聚源数据库"),
        TIANJIN("天天基金网"),
        MYSQL("MySQL数据库"),
        POSTGRESQL("PostgreSQL数据库"),
        ORACLE("Oracle数据库"),
        CSV("CSV数据源"),
        EXCEL("Excel数据源"),
        API("API接口"),
        CUSTOM("自定义数据源");

        private final String description;

        DataSourceType(String description) {
            this.description = description;
        }

        public String getDescription() {
            return description;
        }
    }

    // ========== 补全getter/setter ==========
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getDataSourceName() { return dataSourceName; }
    public void setDataSourceName(String dataSourceName) { this.dataSourceName = dataSourceName; }
    public DataSourceType getDataSourceType() { return dataSourceType; }
    public void setDataSourceType(DataSourceType dataSourceType) { this.dataSourceType = dataSourceType; }
    public String getConnectionConfig() { return connectionConfig; }
    public void setConnectionConfig(String connectionConfig) { this.connectionConfig = connectionConfig; }
    public String getAuthConfig() { return authConfig; }
    public void setAuthConfig(String authConfig) { this.authConfig = authConfig; }
    public String getTableConfig() { return tableConfig; }
    public void setTableConfig(String tableConfig) { this.tableConfig = tableConfig; }
    public String getPythonScript() { return pythonScript; }
    public void setPythonScript(String pythonScript) { this.pythonScript = pythonScript; }
    public String getScheduleConfig() { return scheduleConfig; }
    public void setScheduleConfig(String scheduleConfig) { this.scheduleConfig = scheduleConfig; }
    public Boolean getEnabled() { return enabled; }
    public void setEnabled(Boolean enabled) { this.enabled = enabled; }
    public LocalDateTime getLastSyncTime() { return lastSyncTime; }
    public void setLastSyncTime(LocalDateTime lastSyncTime) { this.lastSyncTime = lastSyncTime; }
    public LocalDateTime getCreateTime() { return createTime; }
    public void setCreateTime(LocalDateTime createTime) { this.createTime = createTime; }
    public LocalDateTime getUpdateTime() { return updateTime; }
    public void setUpdateTime(LocalDateTime updateTime) { this.updateTime = updateTime; }
    public String getCreatedBy() { return createdBy; }
    public void setCreatedBy(String createdBy) { this.createdBy = createdBy; }
    public String getUpdatedBy() { return updatedBy; }
    public void setUpdatedBy(String updatedBy) { this.updatedBy = updatedBy; }
}